﻿/***************************************************************************
 * 文件名：ProjCreatedNofityMgr
 * 功能：
 * 说明：
 * -------------------------------------------------------------------------
 * 创建时间：2023/9/14 13:48:23
 * 创建人：赵旋
 * 邮箱： 1192508693@qq.com
 * =========================================================================
 *
 * 修改人：   
 * 修改时间：   
 * 修改说明：   
 ***************************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ProjCreatedNotify
{
    public class ProjCreatedNofityMgr
    {
        private static List<ProgramAssembly> _ProgramList = null;

        private static bool _Initialized = false;

        private static readonly object _Lock = new object();

        /// <summary>
        /// 注册实例
        /// </summary>
        private static void RegisterInstance()
        {
            _ProgramList = new List<ProgramAssembly>
            {
                //new ProgramAsseble("科研项目创建", "<科研项目所实现接口类的全名称（类的完全限定名&程序集名称）>") 
                new ProgramAssembly("科研项目创建", typeof(ProjCreatedNotification_01).FullName),
                new ProgramAssembly("人事项目创建", typeof(ProjCreatedNotification_02).FullName),
                new ProgramAssembly("基建项目创建", typeof(ProjCreatedNotification_03).FullName),
            };
        }

        /// <summary>
        /// 初始化方法
        /// </summary>
        /// <exception cref="Exception"></exception>
        private static void Init()
        {
            if (_Initialized)
            {
                return;
            }
            lock (_Lock)
            {
                if (_Initialized)
                {
                    return;
                }

                RegisterInstance();
                if (_ProgramList.Any())
                {
                    foreach (var program in _ProgramList)
                    {
                        Type type = Type.GetType(program.Program, false, true);
                        if (type == null)
                        {
                            throw new Exception($"项目创建通知接口实例{program.Name}创建失败,没有找到程序类型,请联系技术人员核查!");
                        }
                        IProjCreatedNotification instance = Activator.CreateInstance(type) as IProjCreatedNotification;
                        if (instance == null)
                        {
                            throw new Exception($"项目创建通知接口实例{program.Name}创建失败,请联系技术人员核查!");
                        }
                        program.Service = instance;
                    }
                }
                _Initialized = true;
            }
        }

        /// <summary>
        /// 项目创建通知
        /// </summary>
        /// <param name="createdProjList"></param>
        public static void Notify(List<ProjCreatedNotifyModel> createdProjList)
        {
            if (createdProjList == null || createdProjList.Count == 0)
            {
                return;
            }
            if (!_Initialized) //如果没有初始，先完成初始化
            {
                Init();
            }
            if (_ProgramList != null && _ProgramList.Count > 0)
            {
                foreach (var program in _ProgramList)
                {
                    if (program.Service != null)
                    {
                        try
                        {
                            program.Service.Notify(createdProjList);
                            // 记录日志
                            Console.WriteLine($"日志模拟(Info)：项目创建通知[{program.Name}]执行成功,通知项目数量{createdProjList.Count},项目编号：{string.Join(",", createdProjList.Select(p => p.ProjCode).ToArray())}");
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine($"日志模拟(Error)：项目创建通知[{program.Name}]执行失败,失败原因：{ex.Message}。" + ex.StackTrace);
                            
                            throw new Exception($"{program.Name}项目创建通知执行失败：{ex.Message}");
                        }
                    }
                }
            }
        }

        #region Assistance Class

        private class ProgramAssembly
        {
            /// <summary>
            /// 程序名称
            /// </summary>
            public string Name { get; set; }

            /// <summary>
            /// 类全限定名
            /// </summary>
            public string Program { get; set; }

            /// <summary>
            /// 接口实例
            /// </summary>
            public IProjCreatedNotification Service { get; set; }

            public ProgramAssembly(string name, string program)
            {
                this.Name = name; 
                this.Program = program;
            }
        } 

        #endregion
    }
}
